package com.qianxunclub.plugin.apidoc.plugin;

import lombok.extern.slf4j.Slf4j;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;

import java.io.*;
import java.util.Arrays;


/**
 * @author chihiro.zhang
 */
@Slf4j
@Mojo(name = "apidoc",defaultPhase=LifecyclePhase.COMPILE)
public class ApiDoc extends AbstractMojo {

    @Parameter(defaultValue = "${project.basedir}")
    private File baseDir;
    @Parameter(defaultValue = "${project.name}")
    private String name;
    @Parameter(defaultValue = "${project.version}")
    private String version;
    @Parameter(defaultValue = "${project.description}")
    private String description;
    @Parameter(defaultValue="http://ip:port/",property = "apidoc.url")
    private String url;
    @Parameter(property = "apidoc.sampleUrl")
    private String sampleUrl;

    @Parameter(defaultValue = "${apidoc.skip}")
    private boolean skip = false;
    @Parameter(defaultValue = "${apidoc.gen}")
    private boolean gen = false;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        if(skip){
            log.warn("apidoc.json没有生成");
            return;
        }
        final String fileName = "apidoc.json";
        String[] fileNames = baseDir.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                if(fileName.equals(name)){
                    return true;
                }
                return false;
            }
        });
        log.info(Arrays.toString(fileNames));
        if(gen || fileNames.length == 0){
            log.info("开始生成apidoc.json...");



            String apidocJson = this.getApiDocJson();
            final String apiDocFilePath = baseDir.getPath() + "/apidoc/" + fileName;
            this.createfile(apiDocFilePath,apidocJson);

            String header = this.getHeaderJson();
            final String headerFilePath = baseDir.getPath() + "/apidoc/apidoc-header.md";
            File file = new File(headerFilePath);
            if(!file.exists()){
                this.createfile(headerFilePath,header);
            }
            log.info("apidoc.json完成");
        } else {
            log.warn("apidoc.json已经存在，没有重新生成");
        }
    }

    private String velocityEngine(String templates,VelocityContext ctx){
        VelocityEngine ve = new VelocityEngine();
        ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
        ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
        Template t = ve.getTemplate(templates);
        StringWriter sw = new StringWriter();
        t.merge(ctx,sw);
        return sw.toString();
    }

    private String getApiDocJson(){
        VelocityContext ctx = new VelocityContext();
        ctx.put("name",name);
        ctx.put("title",name);
        ctx.put("version",version);
        ctx.put("description",description);
        ctx.put("url",url);
        ctx.put("sampleUrl",sampleUrl);
        return this.velocityEngine("templates/apidoc.vm",ctx);
    }

    private String getHeaderJson(){
        VelocityContext ctx = new VelocityContext();
        ctx.put("name",name);
        ctx.put("title",name);
        ctx.put("version",version);
        ctx.put("description",description);
        ctx.put("url",url);
        ctx.put("sampleUrl",sampleUrl);
        return this.velocityEngine("templates/apidoc-header.vm",ctx);
    }

    private void createfile(String filePath, String filecontent){
        BufferedWriter bw = null;
        File file = new File(filePath);
        try {

            if(!file.exists()){
                file.getParentFile().mkdirs();
            }
            file.createNewFile();
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
            bw.write(filecontent);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bw.flush();
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        log.info(filecontent);
    }
}
